package org.bronycorps.mlptss.screen;

import org.bronycorps.mlptss.domain.controller.GameController;
import org.bronycorps.mlptss.domain.layer.ActorLayer;
import org.bronycorps.mlptss.domain.layer.BackgroundLayer;
import org.bronycorps.mlptss.domain.layer.DebugLayer;
import org.bronycorps.mlptss.domain.layer.HudLayer;
import org.bronycorps.mlptss.domain.layer.InGameMenuLayer;
import org.bronycorps.mlptss.domain.layer.MissileLayer;
import org.bronycorps.mlptss.domain.model.Player;
import org.bronycorps.mlptss.domain.model.event.MatchOverEvent;
import org.bronycorps.mlptss.domain.model.event.MatchOverEventListener;
import org.bronycorps.mlptss.manager.CollisionManager;
import org.bronycorps.mlptss.manager.ScreenLoader;
import org.bronycorps.mlptss.manager.TrajectFactory;

import aurelienribon.tweenengine.BaseTween;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenCallback;
import aurelienribon.tweenengine.TweenManager;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.scenes.scene2d.Stage;

public class LevelScreen implements Screen, MatchOverEventListener {

	public static final int STAGE_HEIGHT = 600;
	public static final int STAGE_WIDTH = 1024;
	private ActorLayer actorLayer;
	private CollisionManager collisionManager;
	private DebugLayer debugLayer;
	private GameController gameController;
	private HudLayer hud;
	private boolean isMenuMode = false;
	private float menuKeyCooldown = 0;
	private InGameMenuLayer menuLayer;
	private MissileLayer missileLayer;
	private ShapeRenderer shapeRenderer;
	protected final Stage stage;

	public LevelScreen() {

		this.stage = new Stage(STAGE_WIDTH, STAGE_HEIGHT, true);
		this.shapeRenderer = new ShapeRenderer();
		this.shapeRenderer.setColor(1, 0, 0, 1);

		this.gameController = GameController.getInstance();
		this.gameController.addListener(this);
	}

	public void dispose() {
	}

	public void hide() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onMatchOver(MatchOverEvent event) {
		Player loser = ((Player) event.getSource());
		this.hud.setMessage(loser.getIdPlayer(), "You lose");
		this.hud.setMessage((loser.getIdPlayer() + 1) % 2, "You win");

		Tween.call(new TweenCallback() {

			@Override
			public void onEvent(int type, BaseTween<?> source) {
				LevelScreen.this.gameController.endRound();
			}
		}).delay(5).start(TrajectFactory.getInstance().getTweenManager());
	}

	public void pause() {
		// TODO Auto-generated method stub

	}

	public void render(float delta) {
		Gdx.gl.glClearColor(0.64f, 0.85f, 0.87f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		this.debugLayer.clear();

		if (!this.gameController.isMatchOver()) {
			if (Gdx.input.isKeyPressed(Input.Keys.Q)) {
				this.gameController.getPlayer(0).loseMatch();
			}
			if (Gdx.input.isKeyPressed(Input.Keys.E)) {
				this.gameController.getPlayer(1).loseMatch();
			}
		}

		if (this.menuKeyCooldown > 0) {
			this.menuKeyCooldown -= delta;
		} else {
			if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
				this.menuKeyCooldown = 0.2f;
				this.isMenuMode = !this.isMenuMode;
				this.menuLayer.setVisible(this.isMenuMode);
			}

			if (Gdx.input.isKeyPressed(Input.Keys.S)) {
				((Player) this.actorLayer.getTrack(0).getPlayer().getModel())
						.fireBossEvent();

				this.menuKeyCooldown = 0.2f;
			}
			if (Gdx.input.isKeyPressed(Input.Keys.D)) {
				((Player) this.actorLayer.getTrack(1).getPlayer().getModel())
						.fireBossEvent();

				this.menuKeyCooldown = 0.2f;
			}
		}

		if (this.isMenuMode) {
			if (Gdx.input.isKeyPressed(Input.Keys.Y)) {
				ScreenLoader.getInstance().loadScreen(new MenuScreen());
			}
		} else {
			TrajectFactory.getInstance().getTweenManager().update(delta);
			this.stage.act(delta);
			this.collisionManager.act(delta);
		}

		this.stage.draw();

		this.debugLayer.draw(this.shapeRenderer);

	}

	public void resize(int width, int height) {
		// this.stage.setViewport(width, height, true);

	}

	public void resume() {
		// TODO Auto-generated method stub

	}

	public void show() {
		Gdx.input.setInputProcessor(this.stage);

		BackgroundLayer backgroundLayer = new BackgroundLayer();
		this.stage.addActor(backgroundLayer);

		this.actorLayer = new ActorLayer();
		this.stage.addActor(this.actorLayer);
		this.hud = new HudLayer();
		this.stage.addActor(this.hud);
		this.missileLayer = new MissileLayer(this.actorLayer);
		this.stage.addActor(this.missileLayer);
		this.collisionManager = CollisionManager.getInstance(this.actorLayer,
				this.missileLayer);

		this.menuLayer = new InGameMenuLayer();
		this.menuLayer.setVisible(false);
		this.stage.addActor(this.menuLayer);

		this.debugLayer = DebugLayer.getInstance();

		startIntro();
	}

	private void startIntro() {
		TweenManager tweenManager = TrajectFactory.getInstance()
				.getTweenManager();

		Object[][] msgScript = new Object[4][];
		msgScript[0] = new Object[] { 1.5f,
				"Round " + (GameController.getInstance().getRound() + 1) };
		msgScript[1] = new Object[] { 3f, "" };
		msgScript[2] = new Object[] { 4f, "Ready?" };
		msgScript[3] = new Object[] { 5f, "Go!" };

		for (int i = 0; i < msgScript.length; i++) {
			final String msg = (String) msgScript[i][1];
			final float d = (Float) msgScript[i][0];
			Tween.call(new TweenCallback() {

				@Override
				public void onEvent(int type, BaseTween<?> source) {
					LevelScreen.this.hud.setMessage(0, msg);
					LevelScreen.this.hud.setMessage(1, msg);
				}
			}).delay(d).start(tweenManager);
		}
		Tween.call(new TweenCallback() {

			@Override
			public void onEvent(int type, BaseTween<?> source) {
				LevelScreen.this.hud.setMessage(0, "");
				LevelScreen.this.hud.setMessage(1, "");
				LevelScreen.this.actorLayer.startGame();

			}
		}).delay(5.5f).start(tweenManager);

	}

}
